package hapi.util;

class DynamicImporter implements Dynamic {
	
	var __prefix:String;
	var __data:Dynamic;
	var __convertToUnderscore:Bool;
	
	public function new(data:Dynamic, ?methodPrefix="provide", ?convertToUnderscore=true) {
		this.__prefix = methodPrefix;
		this.__data = data;
		this.__convertToUnderscore = convertToUnderscore;
	}
	
	function resolve(method:String):Dynamic {
		var value:Dynamic = null;
		if (StringTools.startsWith(method, __prefix)) {
			var name:String = __methodNameToField(method);
			value = Reflect.field( __data, name);
		}
		return __createFunction(value);
	}
	
	public static function create<T>(interfaceToIntercep:Class<T>, data:Dynamic, ?prefix:String):T {
		var importer;
		if(prefix == null)
			importer = new DynamicImporter(data);
		else
			importer = new DynamicImporter(data, prefix);
		for (fname in Type.getInstanceFields(interfaceToIntercep)) {
			var paramName = importer.__methodNameToField(fname);
			var func = function() {
				return Reflect.field( data, paramName ); 
			};
			Reflect.setField(importer, fname, func);
		}
		return cast importer;
	}
	
	private function __methodNameToField(method:String) {
		var name:String;
		if (__prefix != "") {
			name = method.substr(__prefix.length + 1);
			name = method.charAt(__prefix.length).toLowerCase() + "" + name;
		}else{
			name = method;
		}
		//trace("name: " + method + " ->" +name+" "+method.substr(__prefix.length + 1)+" "+__prefix);
		if ( __convertToUnderscore ) {
			var buf = new StringBuf();
			for ( i in 0...name.length ) {
				var c = name.charAt(i);
				var l = c.toLowerCase();
				if ( c != l ) {
					buf.add("_" + l);
				}else {
					buf.add(c);
				}
			}
			name = buf.toString();
		}
		return name;
	}
	
	private function __createFunction(result:Dynamic) {
		//trace("create function for |" + result + "|");
		return function() { return result; };
	}
}